﻿using AutoMapper;
using Common.Property;
using DapperExtensions;
using DapperExtensions.Predicate;
using Domain.Sys;
using DTO;
using DTO.DTO.Sys.Module;
using DTO.DTO.Sys.Role;
using IRepository.Sys;
using IServices.Sys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Services.Sys
{
    public class RoleService : IRoleService
    {
        private IMapper _mapper;
        private IModuleRepository _moduleRepository;
        private IRoleRepository _roleRepository;
        private IRoleModuleRepository _roleModuleRepository;
        private IUserRoleRepository _userRoleRepository;
        public RoleService(IMapper mapper, IModuleRepository moduleRepository, IRoleRepository roleRepository,
            IRoleModuleRepository roleModuleRepository, IUserRoleRepository userRoleRepository)
        {
            _mapper = mapper;
            _moduleRepository = moduleRepository;
            _roleRepository = roleRepository;
            _roleModuleRepository = roleModuleRepository;
            _userRoleRepository = userRoleRepository;
        }

        #region 权限菜单
        public async Task<Module> GetModuleById(string id)
        {
            return await _moduleRepository.GetByIdAsync(id);
        }

        public async Task<Tuple<IEnumerable<Module>, int>> GetModulePageList(ModuleQueryDTO dto)
        {
            var pgb = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
            if (!string.IsNullOrWhiteSpace(dto.Keywords))
            {
                pgb.Predicates.Add(Predicates.Field<Module>(f => f.Name, Operator.Like, $"%{dto.Keywords}%"));
            }
            if (!string.IsNullOrWhiteSpace(dto.Status))
            {
                pgb.Predicates.Add(Predicates.Field<Module>(f => f.Status, Operator.Eq, dto.Status));
            }
            var result = await _moduleRepository.GetPageListAsync(dto.PageIndex, dto.PageSize, pgb);
            return result;
        }

        public async Task<Result> SaveModule(ModuleDetailDTO dto, OperatorInfo op)
        {
            var depth = 1;
            if (!string.IsNullOrWhiteSpace(dto.ParentId))
            {
                // 有父级节点，根据父级属性进行赋值
                var parent = await _moduleRepository.GetByIdAsync(dto.ParentId);
                depth = parent.Depth + 1;
            }

            if (string.IsNullOrWhiteSpace(dto.Id))
            {
                var model = _mapper.Map<Module>(dto);
                model.Depth = depth;
                var status = await _moduleRepository.InsertAsync(model, op);

                return status ? Result.Success("保存成功", model.Id) : Result.Failed(-1, "保存失败");

            }
            else
            {
                var model = await _moduleRepository.GetByIdAsync(dto.Id);
                _mapper.Map(dto, model);
                model.Depth = depth;
                var status = await _moduleRepository.UpdateAsync(model, op);

                return status ? Result.Success("保存成功", model.Id) : Result.Failed(-1, "保存失败");
            }
        }

        public async Task<bool> DeleteModule(string id, OperatorInfo op)
        {
            return await _moduleRepository.DeleteAsync(id, op);
        }

        public async Task<bool> DeleteBatchModule(List<string> ids, OperatorInfo op)
        {
            return await _moduleRepository.DeleteBatchAsync(ids, op);
        }
        public async Task<IEnumerable<Module>> GetModuleByParentIdAsync(Module parm)
        {
            return await _moduleRepository.GetByParentIdAsync(parm);
        }

        public List<ModuleFullDTO> GetRecursionModuleList(string parentid, string type, string status, string fullpath)
        {
            var list = new List<ModuleFullDTO>();
            var cmList = _moduleRepository.GetByParentId(new Module() { ParentId = parentid, Type = type, Status = status });
            var childList = _mapper.Map<List<ModuleFullDTO>>(cmList);
            int i = 0;
            childList.ForEach(item =>
            {
                item.FullPath = fullpath + (Convert.ToString(++i)).PadLeft(3, '0');
                list.AddRange(GetRecursionModuleList(item.Id, type, status, item.FullPath));
            });
            list.AddRange(childList);
            return list.OrderBy(o => o.FullPath).ToList();
        }
        #endregion

        #region 角色权限
        public async Task<IEnumerable<string>> GetUserModule(string userId)
        {
            return await _moduleRepository.GetUserModule(userId);
        }

        public bool CheckRoleControllerAction(string userId, string pageUrl)
        {
            return _moduleRepository.CheckRoleControllerAction(userId, pageUrl);
        }

        public async Task<bool> UpdateModules(string roleid, List<RoleModule> modules, OperatorInfo op)
        {

            return await _roleModuleRepository.UpdateModules(roleid, modules, op);
        }

        public async Task<IEnumerable<RoleModule>> GetModuleByRoleId(string roleid)
        {
            return await _roleModuleRepository.GetModuleByRoleId(roleid);
        }
        #endregion

        #region 用户角色
        public async Task<bool> UpdateRoles(string userid, List<UserRole> roles, OperatorInfo op)
        {
            return await _userRoleRepository.UpdateRoles(userid, roles, op);
        }

        public async Task<IEnumerable<UserRole>> GetRoleByUserId(string userid)
        {
            return await _userRoleRepository.GetRoleByUserId(userid);
        }

        public async Task<Role> GetRoleById(string id)
        {
            return await _roleRepository.GetByIdAsync(id);
        }

        public async Task<IEnumerable<Role>> GetRoleList(RoleQueryDTO dto)
        {
            var pgb = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
            if (dto.Status != -1)
            {
                pgb.Predicates.Add(Predicates.Field<Role>(f => f.Status, Operator.Eq, dto.Status));
            }
            return await _roleRepository.GetListAsync();
        }

        public async Task<Tuple<IEnumerable<Role>, int>> GetRolePageList(RoleQueryDTO dto)
        {
            var pgb = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
            if (!string.IsNullOrWhiteSpace(dto.Keywords))
            {
                pgb.Predicates.Add(Predicates.Field<Role>(f => f.Name, Operator.Like, $"%{dto.Keywords}%"));
            }
            if (dto.Status != -1)
            {
                pgb.Predicates.Add(Predicates.Field<Role>(f => f.Status, Operator.Eq, dto.Status));
            }
            var result = await _roleRepository.GetPageListAsync(dto.PageIndex, dto.PageSize, pgb);
            return result;
        }

        public async Task<Result> SaveRole(RoleDetailDTO dto, OperatorInfo op)
        {
            if (string.IsNullOrWhiteSpace(dto.Id))
            {
                var model = _mapper.Map<Role>(dto);
                var status = await _roleRepository.InsertAsync(model, op);

                return status ? Result.Success("保存成功", model.Id) : Result.Failed(-1, "保存失败");

            }
            else
            {
                var model = await _roleRepository.GetByIdAsync(dto.Id);
                _mapper.Map(dto, model);
                var status = await _roleRepository.UpdateAsync(model, op);

                return status ? Result.Success("保存成功", model.Id) : Result.Failed(-1, "保存失败");
            }
        }

        public async Task<bool> DeleteRole(string id, OperatorInfo op)
        {
            return await _roleRepository.DeleteAsync(id, op);
        }

        public async Task<bool> DeleteBatchRole(List<string> ids, OperatorInfo op)
        {
            return await _roleRepository.DeleteBatchAsync(ids, op);
        }
        #endregion
    }
}
